package cn.itcast.zt.example.singleton;

import cn.itcast.zt.annotation.Recommend;
import cn.itcast.zt.annotation.ThreadSafe;

import java.io.Serializable;

/**
 * 静态内部类：最安全
 * 加载一个类时，其内部类不会同时被加载。
 * 一个类被加载，当且仅当其某个静态成员（静态域、构造器、静态方法等）被调用时发生。。
 * 单例结构通过反射无法被破坏，通过序列化与反序列化也无法破坏
 * https://www.cnblogs.com/rjzheng/p/8946889.html
 */
@ThreadSafe
@Recommend
public class SingletonExample10 implements Serializable {

    private static volatile boolean initialized = false ;

    // 私有构造函数
    private SingletonExample10(){
        synchronized (SingletonExample10.class){
            if(!initialized){
                initialized = !initialized ;
            }else {
                throw new RuntimeException("单例已被破坏");
            }
        }
    }

    private static class Singleton {
        private static final SingletonExample10 INSTANCE = new SingletonExample10() ;
    }

    public static SingletonExample10 getInstance(){
        return  Singleton.INSTANCE ;
    }

    /**
     * 方法 readResolve 允许 class 在反序列化返回对象前替换、解析在流中读出来的对象。实现 readResolve 方法，一个 class 可以直接控制反序化返回的类型和对象引用。
     * 方法 readResolve 会在 ObjectInputStream 已经读取一个对象并在准备返回前调用。ObjectInputStream 会检查对象的 class 是否定义了 readResolve 方法。如果定义了，
     * 将由 readResolve 方法指定返回的对象。返回对象的类型一定要是兼容的，否则会抛出 ClassCastException
     * https://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java
     * @return
     */
    private Object readResolve(){
        return getInstance() ;
    }
}
